odhcpd: more fixes for IID calculations
authorDavid Härdeman <[email protected]>
Sun, 26 Oct 2025 13:59:46 +0000 (14:59 +0100)
committerÁlvaro Fernández Rojas <[email protected]>
Mon, 27 Oct 2025 19:03:28 +0000 (20:03 +0100)
commit8f393d55a76e69cc86368a9b5aaf1ba7624f52ea
tree295db7196e3b93eaf21813f0fdfa73612063e098
parentfc27940fe9939f99aeb988d021c7edfa54460123
odhcpd: more fixes for IID calculations

This is the followup to pull request #290.

First, note that in dhcpv6_ia_enum_addrs(), the prefix + IID are currently
combined based on iface->dhcpv6_hostid_len, which is wrong. The latter only
defines the number of bits (typically 12) which should be used to
generate/constrain IIDs, but not the actual IID length.

The actual length of the IID is defined by the length of the prefix
(i.e.  128 - prefix length), the reason this hasn't been noticed is
probably that the higher bits of the IID area in the prefix (the struct
odhcpd_ipdaddr which corresponds to the DHCP server's own IPv6 address
on the interface) are often anyway zero (i.e. people often use an
address like fd00:1234:5678:abcd::1/64 for the server if they have
received a prefix like fd00:1234:5678::/48 from the upstream router).

Second, build_ia() unconditionally writes 64 bits of struct
dhcp_assignment->assigned_host_id (IID) to the struct in6_addr to use for a
given client (i.e. assumes the prefix to be at least /64 or shorter).

This is a first stab at fixing it. I've tried it, and successfully obtained a
lease using a /96 prefix.

There are still some murky corners here though, for example, if
"dhcpv6_hostidlength" is set to 64, there are no real checks that the prefix
length is compatible with that (so we might end up generating an IID of 64
bits, making sure that it is unique and not taken, and then truncate it
silently to a 32 bit IID in case the prefix is /96). But that's a topic for a
different day (and can only be triggered by non-standard configurations).

Signed-off-by: David Härdeman <[email protected]>
Link: https://github.com/openwrt/odhcpd/pull/295
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
src/dhcpv6-ia.c